package main

import (
	"fmt"
	"image"
	"time"

	_ "image/jpeg"
	"os"
	"path"

	"github.com/signintech/gopdf"
	"github.com/tonny-zhang/goutils/fileutils"
	"github.com/tonny-zhang/goutils/logger"
	"github.com/urfave/cli/v2"
)

var (
	// 当前版本号
	version = ""
	// 编译时间
	buildtime = ""
	// 应用名
	appname = ""
)

type paramMergeImgs struct {
	List     []string
	SavePath string
	Auto     bool
	Width    int
	Height   int
}
type imgConf struct {
	Path   string
	Width  float64
	Height float64
}

var logMergeImgs = logger.PrefixLogger("[合并图片]")

func mergeimgs(param paramMergeImgs) {
	if len(param.List) == 0 {
		logMergeImgs.Warn("没有要处理的数据!!")
		return
	}

	// 默认为A4大小
	var WIDTH float64 = 1240
	var HEIGHT float64 = 1754

	var imgsList []imgConf
	for _, item := range param.List {
		if stat, e := os.Stat(item); e == nil {
			if stat.IsDir() {
				if files, e := os.ReadDir(item); e == nil {
					for _, file := range files {
						if !file.IsDir() {
							img := path.Join(item, file.Name())
							imgIn, _ := os.Open(img)
							if config, _, e := image.DecodeConfig(imgIn); e == nil {
								imgsList = append(imgsList, imgConf{
									Path:   img,
									Width:  float64(config.Width),
									Height: float64(config.Height),
								})
							}
							defer imgIn.Close()
						}
					}
				} else {
					logMergeImgs.Warn("[%s]读取出现错误!!", item)
				}
			} else {
				img := item
				imgIn, _ := os.Open(img)
				defer imgIn.Close()
				if config, _, e := image.DecodeConfig(imgIn); e == nil {
					imgsList = append(imgsList, imgConf{
						Path:   img,
						Width:  float64(config.Width),
						Height: float64(config.Height),
					})
				}

			}
		}
	}

	if param.Auto {
		for _, img := range imgsList {
			if img.Width > WIDTH {
				WIDTH = img.Width
			}

			if img.Height > HEIGHT {
				HEIGHT = img.Height
			}
		}
	}

	pdf := gopdf.GoPdf{}

	pdf.Start(gopdf.Config{PageSize: gopdf.Rect{
		W: (WIDTH),
		H: (HEIGHT),
	}, Unit: gopdf.Unit_PX})

	for _, img := range imgsList {
		pdf.AddPage()

		var x, y, w, h = float64(0), float64(0), float64(img.Width), float64(img.Height)
		var wImg, hImg = float64(img.Width), float64(img.Height)

		if wImg > WIDTH || hImg > HEIGHT {
			px := wImg / WIDTH
			py := hImg / HEIGHT

			if px < py {
				w = wImg * HEIGHT / hImg
				h = HEIGHT
			} else {
				w = WIDTH
				h = hImg * WIDTH / wImg
			}
		}

		x = (WIDTH - w) / 2
		e := pdf.Image(img.Path, x, y, &gopdf.Rect{
			W: w,
			H: h,
		})

		if e != nil {
			panic(e)
		} else {
			logMergeImgs.Info("成功添加[%s]", img.Path)
		}
	}

	savepath := param.SavePath
	fileutils.Mkdirp(path.Dir(savepath))

	if e := pdf.WritePdf(savepath); e == nil {
		logMergeImgs.Info("成功保存到[%s]", savepath)
	} else {
		logMergeImgs.Error("保存失败!!")
	}
}
func main() {
	app := cli.NewApp()
	app.Usage = "图片全成pdf工具"

	app.Commands = []*cli.Command{
		{
			Name:  "mergeimgs",
			Usage: "合并图片",
			Flags: []cli.Flag{
				&cli.BoolFlag{
					Name:  "auto",
					Usage: "自动处理图片尺寸",
					Value: false,
				},
				&cli.StringFlag{
					Name:    "savepath",
					Aliases: []string{"o"},
					Usage:   "保存文件路径",
					Value:   "./out.pdf",
				},
			},
			OnUsageError: func(cCtx *cli.Context, err error, isSubcommand bool) error {
				fmt.Println(err, isSubcommand)
				return err
			},
			Action: func(cCtx *cli.Context) error {
				mergeimgs(paramMergeImgs{
					Auto:     cCtx.Bool("auto"),
					List:     cCtx.Args().Slice(),
					SavePath: cCtx.String("savepath"),
				})
				return nil
			},
		},
	}

	app.CommandNotFound = func(cCtx *cli.Context, command string) {
		fmt.Fprintf(cCtx.App.Writer, "[ERROR]没有[%s]\n", command)
	}
	if version == "" {
		version = "development"
	}
	if buildtime == "" {
		buildtime = time.Now().Format("20060102150405")
	}
	app.Version = version + "(" + buildtime + ")"
	app.Run(os.Args)
}
